package com.example.demo.demo;

import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class SemaphoreDemo {


    public static class SemapEntity {
        private final Semaphore semaphore = new Semaphore(10, true);
        private boolean[] seats = new boolean[10];
        private final ReentrantLock lock = new ReentrantLock();

        {
            Arrays.fill(seats, true);
        }

        public void excute(int userId) {
            try {
                log.info("userId:{}开始占位", userId);
                semaphore.acquire();
                int i = place(userId);
                Thread.sleep(100);
                seats[i] = true;
                if (i == -1) {
                    log.info("userId:{}占位失败", userId);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();
                log.info("userId:{}结束占位", userId);
            }
        }

        private int place(int userId) {
            lock.lock();
            int x = -1;
            try {
                for (int i = 0; i < seats.length; i++) {
                    if (seats[i]) {
                        seats[i] = false;
                        x = i;
                        break;
                    }
                }
            } finally {
                lock.unlock();
            }
            return x;
        }
    }

    public static class SemapUser implements Runnable {
        private SemapEntity semapEntity;
        private int userId;

        SemapUser(SemapEntity semapEntity, int userId) {
            this.semapEntity = semapEntity;
            this.userId = userId;
        }

        @Override
        public void run() {
            semapEntity.excute(userId);
        }
    }

    public static void main(String[] args) {
        SemapEntity semapEntity = new SemapEntity();
        for (int i = 0; i < 100; i++) {
            new Thread(new SemapUser(semapEntity, i)).start();
        }
    }

}
